package org.fastsyncer.parser.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.fastsyncer.common.constant.MappingConstant;
import org.fastsyncer.common.entity.Mapping;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * 转换目标源数据
 * 
 * @ClassName: ConvertUtil
 * @Description: 转换目标源数据,支持前后追加、替换
 * @author: YangPei
 * @date: 2017年8月1日 上午9:29:08
 */
public class ConvertUtil {

    /**
     * 批量转换数据源
     * @param sourceMapping
     * @param targetMapping
     * @param rows
     */
	public static List<Map<String, Object>> convertList(Mapping sourceMapping, Mapping targetMapping, List<Map<String, Object>> rows) throws Exception {
	    // 1.将数据源集合转换为目标源集合
	    List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
	    
	    if(rows!=null && !rows.isEmpty()){
	        List<HashMap<String, Object>> sfileds = sourceMapping.getFileds();
            List<HashMap<String, Object>> tfileds = targetMapping.getFileds();
            
            // 2.获取目标源字段与数据源字段映射关系
            Map<String, String> rel = new HashMap<String, String>();
            List<String> tarFileds = new ArrayList<>();
            int size = tfileds.size();
            for (int i = 0; i < size; i++) {
                String tName = (String) tfileds.get(i).get("name");
                String sName = (String) sfileds.get(i).get("name");
                rel.put(tName, sName);
                tarFileds.add(tName);
            }
            
            // 3.转换配置
            Map<String, List<Map<String, String[]>>> convertor = targetMapping.getConvertor();
            
            // 假设条件如下：
            // ID   ID
            // NAME NAME
            // NAME USERNAME
            // row> {id=123,name=张三}  期望实现  {username=张三,name=张三}
            // 4.遍历数据源
            for (Map<String, Object> row : rows) {
                // 目标源数据
                Map<String, Object> r = new HashMap<>();
                for (String tName : tarFileds) {
                    // 4.1获取目标字段对应数据源字段的值
                    String sName = rel.get(tName);
                    Object val = parseValFromMap(row, sName);
                    
                    // 4.2转换值
                    if (convertor!=null && !convertor.isEmpty()) {
                        // 获取目标源转换策略
                        List<Map<String, String[]>> convertTypes = convertor.get(tName);
                        if(convertTypes!=null){
                            val = parse(convertTypes, val);
                        }
                    }
                    
                    // 4.3设置目标字段, 转换后的值
                    r.put(tName, val);
                }
                result.add(r);
            }
	    }
	    return result;
	}
	
    /**
     * 转换数据源
     * @param sourceMapping
     * @param targetMapping
     * @param row
     */
	public static Map<String, Object> convert(Mapping sourceMapping, Mapping targetMapping, JSONArray row) throws Exception {
	    // 1.将数据源集合转换为目标源集合
	    Map<String, Object> result = new HashMap<>();
        if(row!=null){
            List<HashMap<String, Object>> sfileds = sourceMapping.getFileds();
            List<HashMap<String, Object>> tfileds = targetMapping.getFileds();
            
            // 2.获取目标源字段与数据源字段映射关系
            Map<String, String> rel = new HashMap<String, String>();
            List<String> tarFileds = new ArrayList<>();
            int size = tfileds.size();
            for (int i = 0; i < size; i++) {
                String tName = (String) tfileds.get(i).get("name");
                String sName = (String) sfileds.get(i).get("name");
                rel.put(tName, sName);
                tarFileds.add(tName);
            }
            
            // 3.转换配置
            Map<String, List<Map<String, String[]>>> convertor = targetMapping.getConvertor();
            
            // 目标源数据
            for (String tName : tarFileds) {
                // 4.1获取目标字段对应数据源字段的值
                String sName = rel.get(tName);
                Object val = parseValFromJSONArray(row, sName);
                
                // 4.2转换值
                if (convertor!=null && !convertor.isEmpty()) {
                    // 获取目标源转换策略
                    List<Map<String, String[]>> convertTypes = convertor.get(tName);
                    if(convertTypes!=null){
                        val = parse(convertTypes, val);
                    }
                }
                
                // 4.3设置目标字段, 转换后的值
                result.put(tName, val);
            }
        }
        return result;
	}
	
	/**
     * @param row 数据源row
     * @param sName 数据源字段
     * @return 数据源字段的值
     */
    private static Object parseValFromMap(Map<String, Object> row, String sName) {
        Object r = null;
        for (Map.Entry<String, Object> filed : row.entrySet()) {
            String key = filed.getKey();
            if(key.equals(sName)){
                r = filed.getValue();
                break;
            }
        }
        return r;
    }
    
    /**
     * @param row 数据源
     * @param sName 数据源字段
     * @return 数据源字段的值
     * @throws JSONException 
     */
    private static String parseValFromJSONArray(JSONArray row, String sName) throws JSONException {
        String r = null;
        int len = row.length();
        for (int i = 0; i < len; i++) {
            JSONObject f = row.getJSONObject(i);
            String fName = f.getString("name");
            if (StringUtils.equals(sName, fName)) {
                // 判断数据类型是字符串还是数组
                Object object = f.get("value");
                if(object instanceof String){
                    r = f.getString("value");
                }else if(object instanceof JSONArray){
                    // 用“,”拼接值返回
                    r = parseValFromJSONArray(f.getJSONArray("value"));
                }
                break;
            }
        }
        return r;
    }
	
    // 用“,”拼接值返回
	public static String parseValFromJSONArray(JSONArray arr) throws JSONException {
	    StringBuffer val = new StringBuffer();
	    int jLen = arr.length();
        for (int j = 0; j < jLen; j++) {
            // 如果不是最后的一个参数,追加“,”
            if(j<jLen-1){
                val.append(arr.getString(j));
                val.append(",");
                continue;
            }
            val.append(arr.getString(j));
        }
        return val.toString();
    }

    /**
	 * 数据转换
	 * @Title: convert 
	 * @Description: 数据转换,根据类型转换值
	 * @param convertTypes 根据类型
	 * @param value 值
	 * @return: String 转换后的值
	 */
	private static Object parse(List<Map<String, String[]>> convertTypes, Object value) {
	    // 暂时不处理null
	    if(value==null){
	        return value;
	    }
	    
	    // 遍历处理方式[append,replace,append]
	    for (Map<String, String[]> map : convertTypes) {
	        // append : ["asd"]
	        for (Map.Entry<String, String[]> opr : map.entrySet()) {
	            String key = opr.getKey();
	            String[] arg = opr.getValue();
	            if(arg==null || arg.length < 1){
	            	continue;
	            }
	            switch (key) {
	            case MappingConstant.CONVERT_TYPE_PREPEND:
	                // 数据转换类型_追加在前面,例如“张三”追加123 => 123张三
	                value = arg[0] + value;
	                break;
	            case MappingConstant.CONVERT_TYPE_APPEND:
	                // 数据转换类型_追加在后面,例如“张三”追加123 => 张三123
	                value = value + arg[0];
	                break;
	            case MappingConstant.CONVERT_TYPE_REPLACE:
	                // 数据转换类型_替换,例如“张?三”替换?为空字符串 => 张三
		            if(arg.length == 2){
		            	value = value.toString().replace(arg[0], arg[1]);
		            }
	                break;
	            default:
	                break;
	            }
	        }
        }
		return value;
	}

//	public static void main(String[] args) throws JSONException {
////        name = "{name:\"张三\"}";
//	    JSONObject f = new JSONObject();
//	    JSONArray arr = new JSONArray();
//	    arr.put("张三");
//        arr.put("李四");
//	    f.put("name", arr);
////        f.put("name", "张三");
//	    
//        Object object = f.get("name");
//        if(object instanceof String){
//            System.out.println(f.getString("name"));
//        }else{
//            System.out.println(f.getJSONArray("name"));
//        }
//	    
//    }
	
}
